// @flow

function sum(a: number , b: number){
    return a + b
}
sum(1, 2)
sum(1, '2') // flow报语法错误


// Flow原始类型
const a: string = 'ab'
const b: number = NaN // Infinity // 10
const c: boolean = true
const d: null = null
const e: void = undefined
const f: symbol = Symbol('foo')


// Flow数组类型
const arr1: Array<number> = [1, 3, 4]
const arr2: number[] = [1, 2]

// 固定元素个数的数组 叫元组
const foo: [string, number] = ['foo', 100]


// Flow对象类型
const obj1: { foo: string, bar?: number} = {
    foo: 'foo',
    bar: 200
}

const obj3: { [string]: string } = {}
obj3.key1 = 'value1'
obj3.key2 = '100'


// Flow函数类型
function f1(callback: (string, number) => void){
    callback('string', 100)
}
f1(function(str, n){
    return undefined
})


// Flow特殊类型
const a: 'foo' = 'foo'
const type: 'success' | 'warning' | 'danger' = 'success'
type StringOrNumber = string | number
const b: string | number = 100
const c: StringOrNumber = 'str1'

// 注解的类型前面加 ? 还允许null 和 undefined
let gender: ?number = undefined
gender = null
gender = 1


// Flow mixed 和 any类型
// mixed - 任何类型都可以 是强类型
// any - 任何类型都可以 是弱类型（允许随意的隐式类型转换）
// any要少用 主要为了兼容老代码
function passMixed(value: mixed){
    if(typeof value === 'string'){
        value.substr(1)
    }
    if(typeof value === 'number'){
        value * value
    }
}
passMixed(10)
passMixed('str')

function passAny(value: any){
    value.substr(1)
    value * value
}
passAny(null)
passAny(true)


// Flow 类型推断
function square(n){
    return n * n
}
square('100')   // flow报语法错误

// Flow 类型注解
let num: number = 100
num = '10'      // flow报语法错误
function foo(): number {
    return 'a'  // flow报语法错误
}

// Flow对运行环境提供的API的支持
document.getElementById('ab')
document.getElementById(100) // flow报语法错误

const element: HTMLElement | null = document.getElementById('ab')
